package com.sun.gis.tools.jstdt;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

public class TileDownloader {


    public static void main(String[] args) {

        String baseUrl = "https://jiangsu.tianditu.gov.cn/tdtsite05/rest/services/tdtjs/js_img2022_r05/MapServer/tile/";
        String outputDir = "F:\\data\\tdtjs\\2022";
        tileDownloader(baseUrl, outputDir);

    }


    /**
     * 切片下载方法
     *
     * @param baseUrl   在线地图地址
     * @param outputDir 本地下载文件夹
     */
    public static void tileDownloader(String baseUrl, String outputDir) {
        File directory = new File(outputDir);
        if (!directory.exists()) {
            directory.mkdirs(); // 创建目录如果它不存在
        }

        double[] fullExtent = {-180, -90, 180, 90};
        double[] realExtent = {
                116.10358013377254,  // 最小经度
                30.710719079012677, // 最小纬度
                122.09030402444137, // 最大经度
                35.21265930204362   // 最大纬度
        };
        double width4490 = fullExtent[2] - fullExtent[0];  // 经度差
        double height4490 = fullExtent[3] - fullExtent[1]; // 纬度差

        int tileWidth = 256;  // 瓦片宽度，通常为256像素
        int tileHeight = 256; // 瓦片高度，通常为256像素

        double[] resolutions4490 = new double[20]; // 保存从层级1到19的分辨率
        int maxZoom = 19; // 最大层级

        // 计算每个层级的分辨率
        for (int z = 1; z <= maxZoom; z++) {
            resolutions4490[z] = width4490 / (tileWidth * Math.pow(2, z));
        }

        for (int z = 7; z <= maxZoom; z++) {
            int numCols = (int) Math.ceil(width4490 / (resolutions4490[z] * tileWidth));
            int numRows = (int) Math.ceil(height4490 / (resolutions4490[z] * tileHeight));
            for (int x = 0; x < numCols; x++) {
                for (int y = 0; y < numRows; y++) {
                    double tileMinX = -180 + x * resolutions4490[z] * tileWidth;
                    double tileMaxX = tileMinX + resolutions4490[z] * tileWidth;
                    double tileMaxY = 90 - y * resolutions4490[z] * tileHeight;
                    double tileMinY = tileMaxY - resolutions4490[z] * tileHeight;
                    if (tileMinX < realExtent[2] && tileMaxX > realExtent[0] &&
                            tileMinY < realExtent[3] && tileMaxY > realExtent[1]) {
                        final String outputFilePath = outputDir + File.separator + "tile_" + z + "_" + y + "_" + x + ".png";
                        File tileFile = new File(outputFilePath);
                        if (tileFile.exists()) {
                            System.out.println("Tile already exists and will be skipped: " + outputFilePath);
                        } else {
                            final String tileUrl = baseUrl + z + "/" + y + "/" + x;
                            try {
                                downloadTile(tileUrl, outputFilePath);
                                System.out.println("Successfully downloaded: " + outputFilePath);
                            } catch (Exception e) {
                                System.err.println("Failed to download tile " + z + "/" + y + "/" + x + ": " + e.getMessage());
                            }
                        }
                    }
                }
            }
            System.out.println("Scheduled downloads for zoom level " + z);
        }
    }

    public static void downloadTile(String urlString, String outputFile) throws IOException {
        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setConnectTimeout(1000); // 设置连接超时为1秒
        connection.setReadTimeout(1000); // 设置读取超时为1秒

        try {
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                try (InputStream inputStream = connection.getInputStream();
                     FileOutputStream outputStream = new FileOutputStream(outputFile)) {
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                }
            } else {
                throw new IOException("Server returned non-OK status: " + responseCode);
            }
        } catch (IOException e) {
            throw new IOException("Failed to download tile: " + e.getMessage(), e);
        } finally {
            connection.disconnect();
        }
    }

//    public static void downloadTile(String urlString, String outputFile) throws IOException {
//        URL url = new URL(urlString);
//        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//        connection.setRequestMethod("GET");
//        connection.setConnectTimeout(1000); // 设置连接超时为1秒
//        connection.setReadTimeout(1000); // 设置读取超时为1秒
//
//        try {
//            int responseCode = connection.getResponseCode();
//            if (responseCode == HttpURLConnection.HTTP_OK) {
//                try (InputStream inputStream = connection.getInputStream();
//                     BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile))) {
//                    byte[] buffer = new byte[4096];
//                    int bytesRead;
//                    while ((bytesRead = inputStream.read(buffer)) != -1) {
//                        outputStream.write(buffer, 0, bytesRead);
//                    }
//                }
//            } else {
//                throw new IOException("Server returned non-OK status: " + responseCode);
//            }
//        } catch (IOException e) {
//            throw new IOException("Failed to download tile: " + e.getMessage(), e);
//        } finally {
//            connection.disconnect();
//        }
//    }
}

